import { useEffect, useMemo, useRef, useState } from 'react'
import { useSnapshot } from 'valtio'
import { Space, Tooltip } from 'antd'
import { DeleteOutlined, PlusSquareOutlined } from '@ant-design/icons'
import AddWidget from '../AddWidget'
import {
  currentState,
  deleteJsonSchemaItem,
  jsonSchema,
} from '@/store'
import { getAttributeNode, searchId } from '@/utils'

const filterCompents = ['Page', 'Slot']

function SelectComponent() {
  const jsonSchemaSnap = useSnapshot(jsonSchema).value
  const currentStateSnap = useSnapshot(currentState)
  const targetnodeRef = useRef<HTMLElement>()
  const [postition, setPosition] = useState({
    left: 0,
    width: 0,
    height: 0,
    top: 0,
    right: 0,
  })
  const [selectPostition, setSelectPosition] = useState({
    left: 0,
    width: 0,
    height: 0,
    top: 0,
    right: 0,
    maxWidth: 0,
    maxHeight: 0,
  })
  const [actionsState, setActionsState] = useState<{
    $componentName: string
    componentid: string
    hasSlot: boolean | undefined
  }>({ $componentName: '', componentid: '', hasSlot: undefined })
  const [show, setShow] = useState(false)
  const iframeRef = useMemo(
    () => document.getElementById('sanbox-simulator') as HTMLIFrameElement,
    [],
  )

  const getTargetComponent = (ele: HTMLElement) => {
    const targetNode = getAttributeNode(ele, 'componentid') as HTMLElement
    const componentid
      = targetNode
      && targetNode?.getAttribute
      && targetNode.getAttribute('componentid')
    if (
      targetNode
      && targetNode.getBoundingClientRect
      && typeof componentid === 'string'
    ) {
      setShow(true)
      if (targetNode.querySelector('.components-actions'))
        return
      const { left, top, width, height, right }
        = targetNode.getBoundingClientRect()

      setPosition({
        left,
        top,
        width,
        height,
        right,
      })
      const targetItem = searchId(jsonSchemaSnap.componentsTree, componentid)
      const $componentName = targetItem?.$componentName
      const hasSlot = !!targetItem?.hasSlot

      setActionsState({
        $componentName,
        componentid,
        hasSlot: $componentName === 'Slot' ? true : hasSlot,
      })
      return {
        targetNode,
        left,
        top,
        width,
        height,
      }
    }
    else {
      setShow(false)
      return {}
    }
  }

  const click = (e: HTMLElementEventMap['click']) => {
    const { targetNode, left, top, right } = getTargetComponent(
      e.target as HTMLElement,
    ) as any
    const componentid = targetNode?.getAttribute('componentid')
    targetnodeRef.current = targetNode as HTMLElement
    if (targetNode && componentid) {
      currentState.id = componentid
      setSelectPosition({
        left,
        top,
        right,
        width: targetNode.clientWidth,
        height: targetNode.clientHeight,
        maxWidth: iframeRef?.clientWidth,
        maxHeight: iframeRef?.clientHeight,
      })
    }
  }

  useEffect(() => {
    const resize = () => {
      if (targetnodeRef.current) {
        const { left, top, width, height, right }
          = targetnodeRef.current?.getBoundingClientRect()
        setPosition({
          left,
          top,
          width,
          height,
          right,
        })
        setSelectPosition({
          ...selectPostition,
          width: targetnodeRef.current?.clientWidth,
          height: targetnodeRef.current?.clientHeight,
          maxWidth: iframeRef?.clientWidth,
        })
      }
    }
    const observer = new ResizeObserver(() => {
      resize()
      console.log('0000')
    })
    setTimeout(() => {
      if (iframeRef)
        observer.observe(iframeRef)
    }, 100)
    window.addEventListener('resize', resize)
    return () => {
      window.removeEventListener('resize', resize)
    }
  }, [])

  useEffect(() => {
    if (!iframeRef)
      return
    const simulatorBody = (iframeRef as HTMLIFrameElement)?.contentDocument
      ?.body
    // simulatorBody?.addEventListener('mousemove', mousemove);
    simulatorBody?.addEventListener('click', click)
    return () => {
      // simulatorBody?.removeEventListener('mousemove', mousemove)
      simulatorBody?.removeEventListener('click', click)
    }
  }, [jsonSchemaSnap.componentsTree])

  useEffect(() => {
    if (currentStateSnap.id) {
      requestAnimationFrame(() => {
        const simulatorBody = (iframeRef as HTMLIFrameElement)?.contentDocument
          ?.body
        const node = simulatorBody?.querySelector(
          `[componentid='${currentStateSnap.id}']`,
        )
        const { targetNode, left, top, right } = getTargetComponent(
          node as HTMLElement,
        ) as any
        if (targetNode) {
          setSelectPosition({
            left,
            top,
            right,
            width: targetNode.clientWidth,
            height: targetNode.clientHeight,
            maxWidth: iframeRef?.clientWidth,
            maxHeight: iframeRef?.clientHeight,
          })
        }
        else {
          console.warn('没找到 targetNode ---> node', node)
        }
      })
    }
    else {
      setShow(false)
    }
  }, [jsonSchemaSnap.componentsTree, currentStateSnap.id])

  const deleComponent = () => {
    if (actionsState.componentid) {
      deleteJsonSchemaItem(actionsState.componentid as string)
      setShow(false)
      currentState.id = undefined
    }
    else {
      setShow(false)
    }
  }

  return (
    <>
      {/* 选项框 */}
      {currentStateSnap.id && (
        <div
          className="components-actions absolute border-1px border-solid border-brand-primary pointer-events-none "
          style={selectPostition}
        ></div>
      )}
      {/* 组件标签 */}
      <div
        className="absolute"
        style={{
          left: postition.right >= iframeRef?.clientWidth ? iframeRef?.clientWidth : postition.right,
          top: postition.top,
          display: currentStateSnap.id ? 'block' : 'none',
        }}
      >
        <div
          className="flex components-actions rounded-2px absolute  bg-brand-primary p-x-5px p-y-3px text-white text-xs "
          style={
            postition.right + 100 >= iframeRef?.clientWidth
              ? { right: '100%' }
              : {}
          }
        >
          <Space>
            <span className="text-12px">{actionsState.$componentName}</span>
            {actionsState.componentid && actionsState.hasSlot && (
              <AddWidget slotId={actionsState.componentid}>
                <Tooltip
                  title={
                    <span className="text-12px">
                      往 {actionsState.$componentName} 添加一个组件
                    </span>
                  }
                  arrow={false}
                  placement="bottom"
                >
                  <PlusSquareOutlined className="text-12px cursor-pointer" />
                </Tooltip>
              </AddWidget>
            )}
            {!filterCompents.includes(actionsState.$componentName) && <Tooltip
              title={<span className="text-12px">删除</span>}
              arrow={false}
              placement="bottom"
            >
              <DeleteOutlined
                className="text-12px cursor-pointer"
                onClick={deleComponent}
              />
            </Tooltip>}
          </Space>
        </div>
      </div>

    </>
  )
}

export default SelectComponent
